home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 359_11 / patch5.000 / GO32_MSWITCH.ASM < prev    next >
Assembly Source File  |  1991-09-11  |  10KB  |  525 lines

  1. ; This is file MSWITCH.ASM
  2. ;
  3. ; Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. ;
  5. ; This file is distributed under the terms listed in the document
  6. ; "copying.dj", available from DJ Delorie at the address above.
  7. ; A copy of "copying.dj" should accompany this file; if not, a copy
  8. ; should be available from where this file was obtained.  This file
  9. ; may not be distributed without a verbatim copy of "copying.dj".
  10. ;
  11. ; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. ;
  14.  
  15. ; Modified for VCPI Implement by Y.Shibata Aug 5th 1991
  16. ;    History:191,1
  17.     title    switch between real and protected mode
  18.     .386p
  19.  
  20.     include    build.inc
  21.     include    segdefs.inc
  22.     include tss.inc
  23.     include gdt.inc
  24.     include idt.inc
  25.     include vcpi.inc
  26.  
  27. ;------------------------------------------------------------------------
  28.  
  29.     start_data16
  30.  
  31.     extrn    _gdt:gdt_s
  32.     extrn    _idt:idt_s
  33.     extrn    _tss_ptr:word
  34.     extrn    _exception:near
  35.     extrn    _npx:byte
  36.     extrn    _screen_seg:word
  37.     extrn    _use_xms:word
  38.  
  39.     extrn    _vcpi_installed:word    ;VCPI Installed set this not Zero
  40.     extrn    _vcpi_entry:fword
  41.     extrn    _abs_client:dword
  42.  
  43.     public    _was_exception
  44. _was_exception    dw    0    ; exceptions set this to 1
  45.  
  46.     public    _dr, _dr0, _dr1, _dr2, _dr3, _dr6, _dr7
  47. _dr    label    dword
  48. _dr0    dd    0
  49. _dr1    dd    0
  50. _dr2    dd    0
  51. _dr3    dd    0
  52.     dd    0
  53.     dd    0
  54. _dr6    dd    0
  55. _dr7    dd    0
  56.  
  57.     end_data16
  58.  
  59. ;------------------------------------------------------------------------
  60.  
  61.     .286c
  62.     start_bss
  63.  
  64.     extrn    _i_tss:tss_s
  65.     public    _c_tss, _a_tss, _o_tss, _p_tss, _f_tss
  66. _c_tss    label    tss_s    ; for "real mode" state
  67.     db    type tss_s dup (?)
  68. _a_tss    label    tss_s    ; for running program
  69.     db    type tss_s dup (?)
  70. _o_tss    label    tss_s    ; for convenience functions
  71.     db    type tss_s dup (?)
  72. _p_tss    label    tss_s    ; for page faults
  73.     db    type tss_s dup (?)
  74. _f_tss    label    tss_s    ; for page handling
  75.     db    type tss_s dup (?)
  76.  
  77. temp_87c    dw    1 dup (?)
  78. temp_87s    dw    1 dup (?)
  79.  
  80.     end_bss
  81.     .386p
  82.  
  83. ;------------------------------------------------------------------------
  84.  
  85. sound    macro
  86.     local    wait_loop
  87.     local    wait_loop1
  88.     mov    al,033h
  89.     out    061h,al
  90.     mov    ecx,100000h
  91. wait_loop:
  92.     loopd    wait_loop
  93.     mov    al,032h
  94.     out    61h,al
  95.     mov    ecx,100000h
  96. wait_loop1:
  97.     loop    wait_loop1
  98.     endm
  99.  
  100.     start_code16
  101.  
  102.     extrn    __do_load_npx:near
  103.     extrn    _xms_local_enable_a20:near
  104.     extrn    _xms_local_disable_a20:near
  105.  
  106. real_stack    dd    ?
  107. real_idt    dw    0400h, 0000h, 0000h
  108. imask1        db    ?
  109. imask2        db    ?
  110.  
  111.     public    _go32
  112. _go32    proc    near
  113.     push    si
  114. _go32_1:
  115.     mov    ax,DGROUP
  116.     mov    dx,0
  117.     shld    dx,ax,4
  118.     shl    ax,4
  119.     add    ax,_tss_ptr
  120.     adc    dx,0
  121.     mov    _gdt[g_atss].base0,ax
  122.     mov    _gdt[g_atss].base1,dl
  123.     mov    _gdt[g_atss].base2,dh
  124.     mov    bx,_tss_ptr
  125.     and    [bx].tss_eflags,  0ffffbdffh    ; clear NT flag
  126.     and    _c_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  127.     and    _i_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  128.     and    _p_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  129.     and    _f_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  130.     or    _a_tss.tss_eflags,000000200h    ; set IE flag for a_tss only
  131.  
  132.     and    _gdt[g_ctss].stype,0FDh        ; clear busy flag
  133.     and    _gdt[g_atss].stype,0FDh        ; clear busy flag
  134.     and    _gdt[g_itss].stype,0FDh        ; clear busy flag
  135.     and    _gdt[g_ptss].stype,0FDh        ; clear busy flag
  136.  
  137.     mov    _was_exception,0
  138.  
  139.     ; set real_stack for return from _go32
  140.     mov    word ptr cs:real_stack,sp
  141.     mov    word ptr cs:real_stack+2,ss
  142.     mov    eax,0
  143.     mov    ax,sp
  144.     mov    esp,eax        ; make sure it's OK
  145.  
  146.     cli
  147.  
  148. if TOPLINEINFO
  149.     mov    ax,_screen_seg
  150.     mov    es,ax
  151.     mov    word ptr es:[0], 0b00h+'P'
  152.     mov    word ptr es:[2], 0b00h+' '
  153. endif
  154.  
  155. ;    in    al,21h
  156. ;    mov    cs:imask1,al
  157. ;    or    al,01h
  158. ;    out    21h,al
  159.  
  160.     in    al,0a1h
  161.     or    al,20h
  162.     mov    cs:imask2,al
  163.     mov    al,0dfh
  164.     out    0a1h,al
  165.  
  166.     call    set_a20
  167.     cmp    _vcpi_installed,0
  168.     je    short real_to_protect    ;Not VCPI Mode
  169.     mov    esi,_abs_client
  170.     mov    ax,VCPI_MODE_CHANGE
  171.     int    VCPI_REQ        ;Change Protect Mode
  172. end_loop0:
  173.     jmp    short end_loop0        ;Never Come here!! Safety Loop
  174.  
  175. real_to_protect:
  176.     lgdt    fword ptr _gdt[g_gdt]
  177.     lidt    fword ptr _gdt[g_idt]
  178.  
  179.     mov    eax,cr0
  180.     or    al,1
  181.     mov    cr0,eax        ; we're in protected mode!
  182.     db    0eah        ; JMP
  183.     dw    offset go_protect_far_jump
  184.     dw    g_rcode
  185. ;
  186. ;    Entry Protect Mode
  187. ;
  188.     public    _protect_entry
  189. _protect_entry    label    near
  190.  
  191. go_protect_far_jump:
  192.     cli
  193.     mov    ax,g_rdata
  194.     mov    ds,ax
  195.     mov    es,ax
  196.     mov    ss,ax
  197.     mov    sp,word ptr cs:real_stack  ;Need VCPI Inialize
  198.     mov    ax,g_core
  199.     mov    fs,ax
  200.     mov    gs,ax
  201.     mov    eax,0
  202.     mov    cr2,eax    ; so we can tell INT 0D from page fault
  203.  
  204. ;    mov    bx,7870h
  205. ;    call    set_interrupt_controller
  206.  
  207.     mov    eax,_dr0
  208.     mov    dr0,eax
  209.     mov    eax,_dr1
  210.     mov    dr1,eax
  211.     mov    eax,_dr2
  212.     mov    dr2,eax
  213.     mov    eax,_dr3
  214.     mov    dr3,eax
  215.     mov    eax,_dr7
  216.     mov    dr7,eax
  217.  
  218.     cmp    _vcpi_installed,0
  219.     jne    short set_paging_far_jump    ;Now Paging Mode in VCPI
  220.     mov    bx,_tss_ptr
  221.     mov    eax,[bx].tss_cr3
  222.     cmp    eax,0
  223.     je    set_paging_far_jump
  224.     mov    cr3,eax
  225.     mov    eax,cr0
  226.     or    eax,80000000h
  227.     mov    cr0,eax        ; paging enabled!
  228.     db    0eah
  229.     dw    offset set_paging_far_jump
  230.     dw    g_rcode
  231. set_paging_far_jump:
  232.  
  233.     mov    bx,_tss_ptr
  234.     cmp    bx,offset DGROUP:_a_tss
  235.     jne    no_npx_load
  236.     call    __do_load_npx    ; in case it's stored in memory.
  237. no_npx_load:
  238.     cmp    _vcpi_installed,0
  239.     jne    short no_tss_load    ;Now Paging Mode in VCPI
  240.     mov    ax,g_ctss
  241.     ltr    ax
  242. no_tss_load:
  243.     jmpt    g_atss        ; load state from VCPU
  244.  
  245. _go32    endp
  246.  
  247. ; _go_real_mode must follow the task jump, so a task jump to return
  248. ; is valid
  249.  
  250.     public    _go_real_mode
  251. _go_real_mode    proc    near
  252.  
  253.     cli
  254.     mov    ax,g_rdata
  255.     mov    ds,ax
  256.     mov    es,ax
  257.     mov    fs,ax
  258.     mov    gs,ax
  259.     mov    ss,ax
  260.  
  261.     mov    eax,dr6
  262.     mov    _dr6,eax
  263.     ;
  264.     cmp    _vcpi_installed,0
  265.     je    short protect_to_real
  266.     ;
  267.     clts                ;TS Clear
  268. ;    mov    esp,offset _c_tss.tss_stack    ;Local Stack
  269.     mov    eax,DGROUP
  270.     push    eax            ;GS
  271.     push    eax            ;FS
  272.     push    eax            ;DS
  273.     push    eax            ;ES
  274.     push    eax            ;SS
  275.     movzx    eax,word ptr cs:real_stack
  276.     push    eax            ;ESP
  277.     pushfd                ;EFLAGS
  278.     mov    eax,_TEXT
  279.     push    eax            ;CS
  280.     mov    eax,offset back_to_v86
  281.     push    eax            ;EIP
  282.     movzx    esp,sp
  283.     ;
  284.     mov    ax,g_core
  285.     mov    ds,ax
  286.     mov    ax,VCPI_MODE_CHANGE
  287.     call    fword ptr es:_vcpi_entry
  288. end_loop1:
  289.     jmp    short end_loop1        ;Never Come here!! Safety Loop
  290.  
  291. protect_to_real:
  292.     mov    eax,cr0
  293.     and    eax,07ffffff6h ; clear PE, TS, PG
  294.     mov    cr0,eax
  295.  
  296.     db    0eah
  297.     dw    offset back_to_real_far_jump
  298.     dw    _TEXT
  299. ;
  300. ;    Entry Real Mode
  301. ;
  302. back_to_real_far_jump:
  303.  
  304.     lidt    fword ptr cs:real_idt
  305.     lss    sp,cs:real_stack
  306. back_to_v86:
  307. ;    mov    bx,0870h
  308. ;    call    set_interrupt_controller
  309.  
  310. ;    mov    al,cs:imask1
  311. ;    out    21h,al
  312.     mov    al,cs:imask2
  313.     out    0a1h,al
  314.  
  315. if TOPLINEINFO
  316.     mov    ax,_screen_seg
  317.     mov    es,ax
  318.     mov    word ptr es:[0], 0b00h+'R'
  319.     mov    word ptr es:[2], 0b00h+' '
  320. endif
  321.     mov    ax,DGROUP
  322.     mov    ds,ax
  323.     mov    es,ax
  324.     mov    fs,ax
  325.     mov    gs,ax
  326.  
  327.     call    reset_a20
  328.     sti
  329.  
  330.     mov    bx,_tss_ptr
  331.     mov    al,[bx].tss_irqn
  332.     cmp    al,75h
  333.     je    short not_hard    ; for NPX errors
  334.     cmp    al,79h
  335.     je    short not_hard    ; to check for ^C
  336.     cmp    al,70h
  337.     jb    short not_hard
  338.     cmp    al,7fh
  339.     ja    short not_hard
  340.     cmp    al,78h
  341.     jb    short no_move
  342.     sub    al,70h
  343. no_move:
  344.     mov    byte ptr cs:[irq_d+1],al
  345.     jmp    short irq_d_jmp    ; to flush the queue
  346. irq_d_jmp:
  347. irq_d    db    0cdh,0        ; generated INT opcode
  348.     jmp    _go32_1
  349. not_hard:
  350.     pop    si
  351.     ret
  352.  
  353. hexchar    db    '0123456789ABCDEF'
  354.  
  355. _go_real_mode    endp
  356.  
  357. ;------------------------------------------------------------------------
  358.  
  359. dout    macro    a,d
  360.     mov    al,d
  361.     out    a,al
  362.     jmp    $+2
  363.     jmp    $+2
  364.     endm
  365.  
  366. set_interrupt_controller:
  367.     dout    20h,11h
  368.     dout    0a0h,11h
  369.     dout    21h,bh
  370.     dout    0a1h,bl
  371.     dout    21h,4
  372.     dout    0a1h,2
  373.     dout    21h,1
  374.     dout    0a1h,1
  375.     ret
  376.  
  377. ;------------------------------------------------------------------------
  378.  
  379. reset_a20    proc    near
  380.     cmp    _vcpi_installed,0
  381.     jne    short reset_a20_nop
  382.     cmp    _use_xms,0
  383.     je    short reset_a20_local
  384.     call    _xms_local_disable_a20
  385. reset_a20_nop:
  386.     ret
  387.  
  388. reset_a20_local:
  389.     in    al,092h        ; 092h is the system control port "A"
  390.                 ; for PS/2 models
  391.     and    al,not 2    ; this resets the A20 bit in register al
  392.     jmp    SHORT $+2    ; forget the instruction fetch
  393.     out    092h,al        ; set the A20 bit off
  394.     ret
  395. reset_a20    endp
  396.  
  397. set_a20    proc    near
  398.     cmp    _vcpi_installed,0
  399.     jne    short set_a20_nop
  400.     cmp    _use_xms,0
  401.     je    short set_a20_local
  402.     call    _xms_local_enable_a20
  403. set_a20_nop:
  404.     ret
  405.  
  406. set_a20_local:
  407.     pushf
  408.     cli
  409.     in    al,092h        ; 092h is the syste